package com.leoman.post.service.impl;

import com.leoman.adsindex.dao.AdsIndexDao;
import com.leoman.adsindex.entity.AdsIndex;
import com.leoman.banner.dao.BannerDao;
import com.leoman.banner.entity.Banner;
import com.leoman.category.dao.CategoryDao;
import com.leoman.category.entity.Category;
import com.leoman.common.controller.common.CommonController;
import com.leoman.common.service.impl.GenericManagerImpl;
import com.leoman.entity.Constant;
import com.leoman.entity.FileBo;
import com.leoman.floatwin.dao.FloatWinDao;
import com.leoman.floatwin.entity.FloatWin;
import com.leoman.indexapi.service.UserTaskApiService;
import com.leoman.message.dao.MessageDao;
import com.leoman.message.entity.Message;
import com.leoman.post.dao.PostBaseDao;
import com.leoman.post.dao.PostImageDao;
import com.leoman.post.dao.TpPostSubDao;
import com.leoman.post.dao.ZbPostInfoDao;
import com.leoman.post.entity.PostBase;
import com.leoman.post.entity.PostImage;
import com.leoman.post.entity.TpPostSub;
import com.leoman.post.entity.ZbPostInfo;
import com.leoman.post.service.PostBaseService;
import com.leoman.report.dao.ReportDao;
import com.leoman.report.entity.Report;
import com.leoman.user.dao.UserInfoDao;
import com.leoman.user.entity.UserInfo;
import com.leoman.utils.DateUtils;
import com.leoman.utils.FileUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by 蔡琦 on 2016/6/27 0027.
 */
@Service
public class PostBaseServiceImpl extends GenericManagerImpl<PostBase, PostBaseDao> implements PostBaseService {

    @Autowired
    private PostBaseDao postBaseDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private TpPostSubDao tpPostSubDao;

    @Autowired
    private UserInfoDao userInfoDao;

    @Autowired
    private PostImageDao postImageDao;

    @Autowired
    private ZbPostInfoDao zbPostInfoDao;

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private BannerDao bannerDao;

    @Autowired
    private AdsIndexDao adsIndexDao;

    @Autowired
    private FloatWinDao floatWinDao;

    @Autowired
    private ReportDao reportDao;

    @Autowired
    private UserTaskApiService userTaskApiService;

    @Override
    public Page<PostBase> page(final String content, final String mobile, final Long category, final Integer status, final Integer essence, final Integer type, Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, "stick", "id");

        Page<PostBase> page = postBaseDao.findAll(new Specification<PostBase>() {
            @Override
            public Predicate toPredicate(Root<PostBase> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate result = null;
                List<Predicate> predicateList = new ArrayList<>();

                /*UserPost userPost = userPostService.queryByPK((Serializable) root.get("postId").as(Long.class));

                if (StringUtils.isNotEmpty(content)) {
                    Predicate pre = cb.like(userPost.getContent(), "%" + content + "%");
                    predicateList.add(pre);
                }


                if (StringUtils.isNotEmpty(mobile)) {
                    Predicate pre = cb.like(root.get("userLogin").get("username").as(String.class), "%" + mobile + "%");
                    predicateList.add(pre);
                }*/

                if (StringUtils.isNotEmpty(content)) {
                    Predicate pre = cb.like(root.get("content").as(String.class), "%" + content + "%");
                    predicateList.add(pre);
                }

                if (StringUtils.isNotEmpty(mobile)) {
                    Predicate pre = cb.like(root.get("userInfo").get("mobile").as(String.class), "%" + mobile + "%");
                    predicateList.add(pre);
                }

                if (category != null) {
                    Predicate pre = cb.equal(root.get("category").get("id").as(Long.class), category);
                    predicateList.add(pre);
                }

                if (status != null) {
                    Predicate pre = cb.equal(root.get("deleteStatus").as(Integer.class), status);
                    predicateList.add(pre);
                }

                if (type != null) {
                    Predicate pre = cb.equal(root.get("type").as(Integer.class), type);
                    predicateList.add(pre);
                }

                if (essence != null) {
                    Predicate pre = cb.equal(root.get("essence").as(Integer.class), essence);
                    predicateList.add(pre);
                }

                Predicate pre = cb.notEqual(root.get("deleteStatus").as(Integer.class), Constant.POST_STATUS_001);
                predicateList.add(pre);

                if (predicateList.size() > 0) {
                    result = cb.and(predicateList.toArray(new Predicate[]{}));
                }

                if (result != null) {
                    query.where(result);
                }
                return query.getGroupRestriction();
            }

        }, pageRequest);

        return page;
    }

    @Override
    public PostBase getPostInfo(Long postId, Integer type) {
        return postBaseDao.getPostInfo(postId, type);
    }

    @Override
    public Page<PostBase> findPage(final String name, final Long category, final Integer status, final Integer essence, final Integer type, Integer pageNum, Integer pageSize) {

        PageRequest pageRequest = new PageRequest(pageNum - 1, pageSize, Sort.Direction.DESC, "stick", "id");

        Page<PostBase> page = postBaseDao.findAll(new Specification<PostBase>() {
            @Override
            public Predicate toPredicate(Root<PostBase> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate result = null;
                List<Predicate> predicateList = new ArrayList<>();

                if (StringUtils.isNotEmpty(name)) {
                    Predicate pre = cb.like(root.get("name").as(String.class), "%" + name + "%");
                    predicateList.add(pre);
                }

                if (type != null) {
                    Predicate pre = cb.equal(root.get("type").as(Integer.class), type);
                    predicateList.add(pre);
                } else {
                    Predicate pre = cb.ge(root.get("type").as(Integer.class), Constant.POST_TYPE_000);
                    predicateList.add(pre);

                    Predicate pre2 = cb.le(root.get("type").as(Integer.class), Constant.POST_TYPE_002);
                    predicateList.add(pre2);

                }

                /*if (category != null) {
                    Predicate pre = cb.equal(root.get("category").get("id").as(Long.class), category);
                    predicateList.add(pre);
                }*/
                if (category != null) {
                    Predicate pre = cb.equal(root.get("type").as(Integer.class), category);
                    predicateList.add(pre);
                }

                if (status != null) {
                    Predicate pre = cb.equal(root.get("status").as(Integer.class), status);
                    predicateList.add(pre);
                }

                if (essence != null) {
                    Predicate pre = cb.equal(root.get("essence").as(Integer.class), essence);
                    predicateList.add(pre);
                }

                Predicate pre = cb.equal(root.get("deleteStatus").as(Integer.class), Constant.POST_STATUS_000);
                predicateList.add(pre);

                if (predicateList.size() > 0) {
                    result = cb.and(predicateList.toArray(new Predicate[]{}));
                }

                if (result != null) {
                    query.where(result);
                }
                return query.getGroupRestriction();
            }

        }, pageRequest);

        return page;

    }

    @Override
    public List<PostBase> findByCategoryId(Long categoryId, Integer type) {
        return postBaseDao.findByCategoryId(categoryId, type);
    }

    @Override
    public List<PostBase> findByCategoryId(Long categoryId) {
        return postBaseDao.findListCategoryId(categoryId);
    }

    @Override
    public List<PostBase> findListAllByCategoryId(Long categoryId) {
        return postBaseDao.findListAllByCategoryId(categoryId);
    }

    @Override
    public List<PostBase> findListNew(Integer type) {
        return postBaseDao.findListNew(CommonController.getOldDate(), type);
    }

    @Override
    public List<PostBase> findByType(Integer type) {
        return postBaseDao.findByType(type);
    }

    @Override
    public List<PostBase> findByEssence(Integer essence) {
        return postBaseDao.findByEssence(essence);
    }

    @Override
    public List<PostBase> findByStatus(Integer status) {
        return postBaseDao.findByStatus(status);
    }

    @Override
    @Transactional
    public void saveAll(Long postId,
                        Long creatorList,
                        String name,
                        Long typeList,
                        Integer type,
                        String content,
                        String startDate,
                        String description,
                        String endDate,
                        String[] tpSub,
                        String[] tpSubs,
                        String isActivity,
                        MultipartRequest multipartRequest) throws IOException, ParseException {
        PostBase postBase;
        if (postId == null) {
            postBase = new PostBase();
            postBase.setCreateDate(System.currentTimeMillis());
        } else {
            postBase = postBaseDao.findOne(postId);
            /*category = postBase.getCategory();
            category.setCount(category.getCount() - 1);
            categoryDao.save(category);*/
        }

        MultipartFile multipartFile = multipartRequest.getFile("cover");
        if (null != multipartFile) {
            // 保存帖子封面
            FileBo fileBo = FileUtil.save(multipartFile, true);
            postBase.setAvater(fileBo.getPath());
            postBase.setSuolue(fileBo.getSuoluePath());
            postBase.setWidth(fileBo.getWidth());
            postBase.setHeight(fileBo.getHeight());
        }

        postBase.setName(name);

        // 增加用户发帖数
        /*UserInfo userInfo = userInfoDao.findOneByNickname(Constant.YULEJUN);
        if (userInfo != null) {
            userInfo.setPosts(userInfo.getPosts() + 1);
            userInfoDao.save(userInfo);
        }
        postBase.setUserInfo(userInfoDao.findOneByNickname(Constant.YULEJUN));*/

        postBase.setType(type);

        // 增加分类数
        /*category = categoryDao.findOne(typeList);
        category.setCount(category.getCount() + 1);
        categoryDao.save(category);*/

        postBase.setCategory(categoryDao.findOne(typeList));
        if (creatorList != null) {
            postBase.setUserInfo(userInfoDao.findOne(creatorList));
        }
        postBase.setUpdateDate(System.currentTimeMillis());

        if (type.equals(Constant.POST_TYPE_000)) {

            // 普通贴
            postBase.setContent(content);
            //postBase.setDescription(description);
            postBase.setStatus(3);

            if (StringUtils.isNotEmpty(isActivity)) {
                postBase.setIsActivity(1);
            }

            postBaseDao.save(postBase);
        } else if (type.equals(Constant.POST_TYPE_001)) {

            // 直播贴
            postBase.setStatus(0);
            postBase.setStartDate(DateUtils.stringToLong(startDate, "yyyy-MM-dd hh:mm:ss"));
            postBaseDao.save(postBase);
        } else if (type.equals(Constant.POST_TYPE_002)) {

            // 投票帖
            postBase.setContent(content);
            postBase.setStatus(1);
            postBase.setEndDate(DateUtils.stringToLong(endDate, "yyyy-MM-dd hh:mm:ss"));
            postBaseDao.save(postBase);

            //修改投票对象
            saveModifyTpPostSub(postBase, tpSubs, multipartRequest);

            //新增投票对象
            saveNewTpPostSub(postBase, tpSub, multipartRequest);

            // 增加该帖子分类的浏览量
            userTaskApiService.addPostPlayNum(postBase, 0, 1);
        }
    }

    @Override
    @Transactional
    public void addZB(HttpServletRequest request, Long postId, Long creatorId, String tempAddImageIds1, String tempDelImageIds, Integer status) throws UnsupportedEncodingException {
        PostBase postBase = postBaseDao.findOne(postId);
        if (status == null) {
            postBase.setStatus(postBase.getStatus());
        } else {
            postBase.setStatus(2);
        }
        postBase.setUpdateDate(System.currentTimeMillis());
        postBaseDao.save(postBase);

        UserInfo userInfo = userInfoDao.findOne(creatorId);

        String msg = request.getParameter("content");

        ZbPostInfo zbPostInfo = new ZbPostInfo();
        zbPostInfo.setPostBase(postBase);
        zbPostInfo.setAvater(userInfo.getAvater());
        zbPostInfo.setNickname(userInfo.getNickname());
        zbPostInfo.setContent(msg);
        zbPostInfo.setCreateDate(System.currentTimeMillis());
        zbPostInfo.setUpdateDate(System.currentTimeMillis());
        zbPostInfoDao.save(zbPostInfo);

        String[] addImageIds1;
        if (StringUtils.isNotEmpty(tempAddImageIds1)) {
            addImageIds1 = tempAddImageIds1.split(",");

            // 保存图片集合
            PostImage image;
            for (String imageId : addImageIds1) {
                if (null != imageId && !imageId.equals("")) {
                    image = postImageDao.findOne(Long.parseLong(imageId));
                    //image.setImage();
                    image.setType(Constant.POST_TYPE_001);
                    image.setPostId(zbPostInfo.getId());

                    postImageDao.save(image);
                }
            }
        }

        // 删除图片集合
        deleteImgs(tempDelImageIds);

        userTaskApiService.addPostPlayNum(postBase, 0, 1);
    }

    @Override
    @Transactional
    public void saveZB(HttpServletRequest request, Long postId, Long creatorList, String name, Long typeList, Integer type, String startDate, String[] description, String tempDelImageIds, MultipartRequest multipartRequest) throws IOException, ParseException {
        PostBase postBase = postBaseDao.findOne(postId);
        MultipartFile multipartFile = multipartRequest.getFile("cover");
        if (null != multipartFile) {
            FileBo fileBo = FileUtil.save(multipartFile, true);
            postBase.setAvater(fileBo.getPath());
            postBase.setSuolue(fileBo.getSuoluePath());
        }
        postBase.setName(name);

        // 先删除原有的帖子分类数量
        /*Category category = postBase.getCategory();
        category.setCount(category.getCount() - 1);
        categoryDao.save(category);*/

        // 后新增帖子分类数量
        /*Category category1 = categoryDao.findOne(typeList);
        category1.setCount(category1.getCount() + 1);
        categoryDao.save(category1);*/

        postBase.setCategory(categoryDao.findOne(typeList));
        postBase.setType(type);
        if (creatorList != null) {
            postBase.setUserInfo(userInfoDao.findOne(creatorList));
        }
        postBase.setStartDate(DateUtils.stringToLong(startDate, "yyyy-MM-dd hh:mm:ss"));
        postBaseDao.save(postBase);

        List<ZbPostInfo> zbPostInfoList = zbPostInfoDao.getPostInfo(postId);
        if (zbPostInfoList.size() > 0) {
            for (int i = 0; i < description.length; i++) {
                if (StringUtils.isNotEmpty(description[i])) {
                    //Long id = zbPostInfoList.get(i).getId();
                    zbPostInfoList.get(i).setContent(description[i]);
                    zbPostInfoList.get(i).setPostBase(postBase);

                    zbPostInfoDao.save(zbPostInfoList.get(i));
                }
            }
        }

        // 删除图片集合
        deleteImgs(tempDelImageIds);
    }

    @Override
    @Transactional
    public Integer saveUserPost(Long creatorId, Long category, String description, String tempAddImageIds1, String tempDelImageIds) {
        String[] addImageIds1;

        String desc = description;

        description = description.replaceAll("\n", "").replaceAll("\r", "");

        // 判断用户发帖字数限制
        UserInfo userInfo = userInfoDao.findOne(creatorId);
        if (userInfo.getIsCreator() == 1 && userInfo.getLevel() == 0 && description.length() > 1000) {

            //主创等级为0，字数1000字以内
            return 2;
        } else if (userInfo.getIsCreator() == 0 && userInfo.getLevel() < 5 && description.length() > 200) {

            //用户等级小于5，字数200以内
            return 3;
        } else if (userInfo.getIsCreator() == 0 && userInfo.getLevel() >= 5 && userInfo.getLevel() < 10 && description.length() > 500) {

            //用户等级大于等于5小于10，字数500以内
            return 4;
        }

        PostBase postBase = new PostBase();
        postBase.setType(Constant.POST_TYPE_003);
        postBase.setStatus(0);

        // 增加帖子分类数量
        /*Category category1 = categoryDao.findOne(category);
        category1.setCount(category1.getCount() + 1);
        categoryDao.save(category1);*/

        postBase.setCategory(categoryDao.findOne(category));

        // 增加用户发帖数
        /*UserInfo userInfo = userInfoDao.findOne(creatorId);
        userInfo.setPosts(userInfo.getPosts() + 1);
        userInfoDao.save(userInfo);*/

        postBase.setUserInfo(userInfoDao.findOne(creatorId));
        postBase.setName(desc);
        postBase.setContent(desc);
        postBase.setCreateDate(System.currentTimeMillis());
        postBase.setUpdateDate(System.currentTimeMillis());
        postBaseDao.save(postBase);

        if (StringUtils.isNotEmpty(tempAddImageIds1)) {
            addImageIds1 = tempAddImageIds1.split(",");
            if (addImageIds1.length > 9) {
                return 5;
            }
            // 保存图片集合
            PostImage image;
            for (String imageId : addImageIds1) {
                if (null != imageId && !imageId.equals("")) {
                    image = postImageDao.findOne(Long.parseLong(imageId));
                    //image.setImage();
                    image.setType(3);
                    image.setPostId(postBase.getId());

                    postImageDao.save(image);
                }
            }
        }

        // 删除图片集合
        deleteImgs(tempDelImageIds);

        postBaseDao.save(postBase);

        userTaskApiService.addPostPlayNum(postBase, 0, 1);

        return 1;
    }

    @Override
    public List<PostBase> findByDeleteStatus() {
        return postBaseDao.findByDeleteStatue();
    }

    @Override
    @Transactional
    public Integer deletePost(Long postId) {
        PostBase postBase = postBaseDao.findOne(postId);

        // 是否链接到广告banner
        List<Banner> bannerList = bannerDao.findByTypeAndWorkId(Constant.POSITION_000, postId);
        if (bannerList.size() != 0) {
            return 2;
        }

        // 是否链接到首页推荐
        List<AdsIndex> adsIndexList = adsIndexDao.findByTypeAndWorkId(Constant.POSITION_000, postId);
        if (adsIndexList.size() != 0) {
            return 2;
        }

        // 是否链接到浮窗广告
        List<FloatWin> floatWinList = floatWinDao.findByTypeAndWorkId(Constant.POSITION_000, postId);
        if (floatWinList.size() != 0) {
            return 2;
        }

        // 是否有举报
        List<Report> reportList = reportDao.findListByParams(postId);
        if (reportList.size() != 0) {
            return 2;
        }

        postBase.setDeleteStatus(Constant.POST_STATUS_001);
        postBaseDao.save(postBase);

        // 分类数量减1
        /*Category category = postBase.getCategory();
        if (category != null) {
            category.setCount(category.getCount() - 1);
            categoryDao.save(category);
        }*/

        // 新增删帖消息
        Message message = new Message();
        message.setUserId(postBase.getUserInfo().getId());
        message.setPostId(postId);
        message.setType(1);
        message.setToObject("0");
        message.setTitle("帖子被删除");
        message.setContent("管理员删除");
        messageDao.save(message);

        return 1;
    }

    @Override
    public List<PostBase> findByUserId(Long userId) {
        return postBaseDao.findByUserId(userId);
    }

    @Override
    public PostBase findOneById(Long postId) {
        return postBaseDao.findOne(postId);
    }

    // 删除图片集合
    public void deleteImgs(String ids) {

        if (StringUtils.isNotEmpty(ids)) {
            String[] newIds = ids.split(",");
            PostImage image;
            for (String imageId : newIds) {
                if (null != imageId && !imageId.equals("")) {
                    image = postImageDao.findOne(Long.parseLong(imageId));
                    postImageDao.delete(image);
                }
            }
        }
    }

    // 保存修改后的投票对象
    public void saveModifyTpPostSub(PostBase postBase, String[] tpSubs, MultipartRequest multipartRequest) throws IOException {
        List<TpPostSub> tpPostSubList = tpPostSubDao.getPostInfo(postBase.getId());
        if (tpPostSubList.size() > 0) {
            for (int i = 0; i < tpSubs.length; i++) {
                if (StringUtils.isNotEmpty(tpSubs[i])) {
                    tpPostSubList.get(i).setName(tpSubs[i]);
                    tpPostSubList.get(i).setPostBase(postBase);
                    MultipartFile file = multipartRequest.getFile("avaters" + tpPostSubList.get(i).getId());
                    if (null != file) {
                        FileBo fileBo = FileUtil.save(file, true);
                        tpPostSubList.get(i).setCover(fileBo.getPath());
                        tpPostSubList.get(i).setSuolue(fileBo.getSuoluePath());
                    }
                    tpPostSubDao.save(tpPostSubList.get(i));
                }
            }
        }
    }

    // 保存新增投票对象
    public void saveNewTpPostSub(PostBase postBase, String[] tpSub, MultipartRequest multipartRequest) throws IOException {
        for (int i = 0; i < tpSub.length; i++) {
            if (StringUtils.isNotEmpty(tpSub[i])) {
                TpPostSub tpPostSub = new TpPostSub();
                tpPostSub.setName(tpSub[i]);
                tpPostSub.setCount(0);
                tpPostSub.setPostBase(postBase);
                List<MultipartFile> multipartFiles = multipartRequest.getFiles("avater");
                if (multipartFiles.size() > 0) {
                    FileBo fileBo = FileUtil.save(multipartFiles.get(i), true);
                    tpPostSub.setCover(fileBo.getPath());
                    tpPostSub.setSuolue(fileBo.getSuoluePath());
                }
                tpPostSubDao.save(tpPostSub);
            }
        }
    }
}
